OilTrack · ตู้คีออสก์ที่หัวจ่าย (Gateway kiosk state machine) Prototype V.2 · 2026-09
Spheresoft Co., Ltd. เอกสารอ้างอิงต้นแบบ — ไม่ใช่สัญญาส่งมอบ

OilTrack · ตู้คีออสก์ที่หัวจ่าย

จอที่ติดตั้งอยู่กับหัวจ่ายจริง ทำหน้าที่เดียว: บอกคนที่ยืนอยู่หน้าตู้ว่าตอนนี้หัวจ่ายนี้อยู่ในสถานะอะไร และต้องทำอะไรต่อ ตู้ไม่รับการกดใด ๆ — ทุกการตัดสินใจเกิดในแอปคนขับหรือที่หลังบ้าน เอกสารนี้อธิบาย 11 สถานะ ลำดับความสำคัญที่ใช้เลือกสถานะ กฎของมาตรวัด และวิธีทดสอบทุกสถานะ

อ่านคู่กับ Doc - Business Flow (§1 และ §3 อธิบายฝั่งคนขับและบัญชีของเหตุการณ์เดียวกัน) และ Doc - Overview (§7 ตารางกำหนดเวลา)

1 · อุปกรณ์และการวางองค์ประกอบ

จอ 7 นิ้ว 1024 × 600 พิกเซล คงที่ ขับด้วยคอมพิวเตอร์บอร์ดเดียว ไม่มีการเลื่อนจอในทุกสถานะ ทุกอย่างต้องพอดีในกรอบนี้เสมอ แม้หัวจ่ายจะมีหัวจ่ายย่อย 1–4 หัว คนขับยืนห่างประมาณหนึ่งช่วงแขนกลางแดด ตัวอักษรจึงไม่เล็กกว่า 13px และตัวเลขหลักของแต่ละสถานะอยู่ที่ 54–104px

OilTrack Gateway DP-0005 หัวจ่ายลานจอด 2 state chip 09:41 · 02:41 UTC
main panel · flex 1
เนื้อหาของสถานะปัจจุบัน — QR + รหัส, การ์ดคำขอ, เลขหัวจ่ายย่อย, มาตรวัดสด หรือใบสรุป · padding 24–32px
info rail · 280px
หัวจ่ายนี้คือหัวไหน · ประจำที่หรือบนรถ · สถานี/ทะเบียน · เลข gateway · ชนิดน้ำมันที่จ่ายได้ · ตารางหัวจ่ายย่อยพร้อมจุดสถานะ
NET · SRV 34ms · TUN 10.8.0.14 · UTC 02:41:07Z · UP 14:22 · GW-1001 · FW 1.4.2 · STATE idle
รูปที่ 1 — โครงจอสี่แถบ หัวแถบ 52px · เนื้อหา · แถบข้อมูลด้านขวา 280px · แถบดีบัก 34px ที่แสดงทุกสถานะ ไม่มีสถานะใดซ่อนแถบนี้ เพราะช่างต้องอ่านค่าเชื่อมต่อได้ทันทีที่เดินถึงตู้

แถบข้อมูลด้านขวาตอบคำถามเดียวเสมอว่า “ผมยืนอยู่ที่หัวจ่ายไหน” — ลำดับคือ ตำแหน่งติดตั้ง (สถานีประจำที่ / รถน้ำมันเคลื่อนที่ + ทะเบียน) · สถานีหรือตัวรถ · เลข gateway · ชนิดน้ำมันที่หัวนี้จ่ายได้ · แล้วจึงเป็นหัวจ่ายย่อยเรียงตามลำดับเป็นตาราง 2×2 พร้อมจุดสถานะ (เขียว = ว่าง, น้ำเงิน = กำลังใช้งาน) สถานะ “กำลังใช้งาน” มาจากเลขหัวจ่ายย่อยของคำขอที่ถืออยู่ ไม่ใช่จากตัวล็อกเอง

2 · สถานะทั้ง 11 และเส้นทางเปลี่ยนสถานะ

#0 boot
ตรวจ 6 อย่าง
#1 idle
QR 21×21 + รหัส 6 หลัก · วงแหวน 30 วินาที · คำแนะนำ 3 ขั้น
#8 locked
ปิดจ่ายจากส่วนกลาง
#9 error
ไม่มีลิงก์ไปส่วนกลาง — ไม่แสดง QR
สแกน/กรอกรหัส
#2 binding
การ์ดคำขอ + นับถอยหลัง 2 นาที · ยืนยันในแอป
#3 bound
เลขหัวจ่ายย่อย 64px · นับถอยหลัง 5 นาที · แดงเมื่อเหลือไม่ถึงนาที
#4 progress
มาตรวัดสด 104px · อัตราไหล · เวลาที่ใช้
หมดเวลา / ถูกยกเลิก
#2 หมดเวลา → กลับ #1
คำขอถอยเป็น อนุมัติแล้ว · ปลดหัวจ่าย
#3 หมดเวลา → #1
คำขอถูกยกเลิก · ปลดหัวจ่าย
#6 aborted
ถูกดึงกลางคัน · เหตุผลและผู้สั่ง · ค้าง 8 วินาที → #1
จ่ายจบ
#5 complete
ลิตรจริง 84px · ผลต่างกับที่อนุมัติ · ใบยืนยันการส่งข้อมูล · ค้าง 10 วินาที → #1
#7 degraded
ไม่ใช่หน้าจอ — เป็นป้ายสีเหลืองบน #2/#3/#4 เมื่อลิงก์หลุด จ่ายต่อได้
#10 recovery
ไฟดับกลางการจ่าย · ปิดที่เลขมาตรวัดล่าสุด · ตั้งธง
รูปที่ 2 — เส้นทางเปลี่ยนสถานะ กรอบน้ำเงินคือเส้นทางปกติ #1 → #2 → #3 → #4 → #5 สถานะที่เหลือคือทางแยกที่เกิดจากเงื่อนไขจริง ไม่ใช่การกดข้ามหน้า
# คีย์ เข้าเมื่อ ออกเมื่อ ตัวเลขหลักบนจอ
0bootเปิดเครื่อง / รีบูตตรวจครบ 6 ข้อ แล้วแตกไปตามเงื่อนไขจริงแถบความคืบหน้าแบบกำหนดค่าได้
1idleหัวจ่ายว่าง เปิดจ่าย และมีลิงก์มีคำขอมาจองหัวจ่ายรหัส 6 หลัก (mono)
2bindingสแกน QR หรือกรอกรหัสถูกยืนยันในแอป → #3 · ครบ 2 นาที → #1เวลาที่เหลือ
3boundคนขับยืนยันการผูกในแอปเริ่มจ่าย → #4 · ครบ 5 นาที → คำขอถูกยกเลิกเลขหัวจ่ายย่อย 64px
4progressมาตรวัดเริ่มเดินถึงเพดาน หรือหยุดจ่ายครบ 1 นาที → #5ลิตรสด 104px
5completeคำขอปิดด้วยลิตรจริงค้าง 10 วินาที → #1ลิตรจริง 84px
6abortedคำขอถูกยกเลิก/ปลดขณะจองหรือผูกอยู่ค้าง 8 วินาที → #1เหตุผล + ผู้สั่ง
7ลิงก์ไปส่วนกลางหลุดขณะมีงานอยู่ลิงก์กลับมาป้ายเหลือง + จำนวนรายการที่รอส่ง
8lockedผู้ดูแลระบบปิดการจ่ายของหัวนี้เปิดการจ่ายอีกครั้งข้อความปิดการจ่าย
9errorตู้ว่างและไม่มีลิงก์ลิงก์กลับมา → #1ไม่มี QR — จงใจ
10recoveryร่องรอยในเครื่องตรงกับคำขอที่ถืออยู่ หลังรีสตาร์ตปิดคำขอที่เลขล่าสุด แล้วกลับ #1ลิตรล่าสุดที่วัดได้
ตารางที่ 1 — เงื่อนไขเข้า-ออกของทุกสถานะ #7 ไม่ใช่หน้าจอแยก จึงไม่มีคีย์ของตัวเอง

3 · ลำดับความสำคัญในการเลือกสถานะ

ตู้ไม่ได้ “ย้ายสถานะ” ตามเหตุการณ์ แต่คำนวณสถานะใหม่ทุกครั้ง จากสภาพจริง ณ ขณะนั้น ลำดับด้านล่างสำคัญทุกบรรทัด กฎแรกที่ตรงคือสถานะที่แสดง

1#10 recoveryมีร่องรอยการจ่ายที่ค้างและตรงกับคำขอที่หัวนี้ถืออยู่
2#4 → #2 → #3มีงานที่ยังมีชีวิตอยู่บนหัวนี้ (กำลังจ่าย ก่อน รอยืนยัน ก่อน ผูกแล้ว)
3#5 completeมีใบสรุปที่ยังอยู่ในช่วง 10 วินาที
4#6 abortedมีประกาศการยกเลิกที่ยังอยู่ในช่วง 8 วินาที
5#9 errorไม่มีลิงก์ไปส่วนกลาง
6#8 lockedหัวนี้ถูกปิดการจ่ายจากส่วนกลาง
7#1 idleไม่เข้าเงื่อนไขใดข้างบน — พร้อมรับการสแกน
รูปที่ 3 — ลำดับใน resolveState() งานที่มีชีวิตอยู่สำคัญกว่าทั้งลิงก์และการล็อก
เหตุผลที่ลำดับต้องเป็นแบบนี้: ถ้าลิงก์มาก่อนงาน ตู้จะตกไป #9 ทั้งที่น้ำมันกำลังไหล — คนหน้าตู้จะไม่เห็นมาตรวัดของตัวเอง ระบบจึงเลือกลดระดับเป็นป้าย #7 แทน และถ้าการล็อกมาก่อนงาน การสั่งปิดจ่ายกลางคันจะบังหน้าจอที่กำลังจ่าย หรือกลืนใบสรุป #5 หายไป การปิดจ่ายจึงมีผลกับการผูกครั้งใหม่เท่านั้น

4 · กฎของมาตรวัด

ลิตรเดินเมื่อไร
เดินเฉพาะตอนที่สถานะที่คำนวณได้คือ #4 เท่านั้น ไม่มีการเดินอยู่เบื้องหลังหน้าจออื่น เปิดหน้าจอทิ้งไว้แล้วตัวเลขจะไม่ไหลไปเอง
เพดานลิตร
ใช้ลิตรที่อนุมัติ ถ้าไม่มีใช้ลิตรที่ขอ คำขอแบบเต็มถังก็มีเพดาน — ระบบบังคับใช้แต่ไม่แสดง และไม่แสดงความจุถังเป็นตัวเลขในทุกกรณี
การจ่ายที่ตู้นี้ไม่ได้เริ่ม
รับมาที่เลขที่มาตรวัดรายงาน และปล่อยไว้ที่ #1 พร้อมหมายเหตุ “เริ่มก่อนหน้านี้” — การเปิดหน้าจอต้องไม่ไล่คำขอของคนอื่นไปจนจบ
ร่องรอยสำหรับกู้คืน
ระหว่างจ่าย ตู้เขียน {reqId, litres, at} ลงเครื่องทุก 2 วินาที และล้างเมื่อขึ้น #5 หรือถูกยกเลิก · #10 เกิดเฉพาะเมื่อร่องรอยตรงกับคำขอที่ถืออยู่ การโหลดหน้าเปล่า ๆ ไม่ทำให้กู้คืน
ตารางที่ 2 — สี่กฎที่กันไม่ให้ตัวเลขลิตรเพี้ยน ทั้งสี่ข้อเป็นข้อบังคับ ไม่ใช่การปรับแต่ง

5 · การบังคับเวลาสองทาง

ตู้บังคับเวลาสด เพราะเป็นเจ้าของหน้าจอ ส่วน DB.sync() เป็นตัวสำรองสำหรับตู้ที่ออฟไลน์ รีบูต หรือไม่ได้เปิดอยู่ ทั้งสองทางเรียกฟังก์ชันชุดเดียวกันจึงให้ผลตรงกัน — ไม่มีกรณีที่ “ตู้ว่าแบบหนึ่ง หลังบ้านว่าอีกแบบ”

ตู้เปิดอยู่
นับถอยหลังบนจอถึง 0 → ตู้เรียกฟังก์ชันปล่อย/ยกเลิกทันที คนที่ยืนอยู่เห็นผลในวินาทีนั้น
ตู้ไม่ได้เปิด / ออฟไลน์
รอบกวาดของหน้าอื่นที่เปิดอยู่ (ทุก 60 วินาที) ทำสิ่งเดียวกัน คำขอไม่ค้างล็อกรถทิ้งไว้แม้ไม่มีใครเปิดตู้
ข้อยกเว้นที่ตั้งใจ: แถวข้อมูลตัวอย่างที่สถานะ bound โดยไม่มีกำหนดเวลาเริ่มเติม และแถว binding ที่ไม่มีกำหนดเวลายืนยัน จะถูกข้ามโดยรอบกวาด และจอจะไม่แสดงนับถอยหลัง แถบเวลา หรือคำเตือน — ไม่ใช่แสดง 0:00 ค้างไว้ การตั้งเวลาให้แถวเหล่านี้เป็นการกระทำที่ต้องสั่งเอง
รูปที่ 4 — การบังคับเวลาสองทางและข้อยกเว้นของข้อมูลตัวอย่าง ค่าเวลาทั้งหมด (30 วินาที · 2 นาที · 5 นาที · 1 นาที · 10 วินาที · 8 วินาที) มาจาก config ไม่ใช่ค่าคงที่ในหน้าจอ

6 · แถบดีบักและแผงทดสอบ

แถบดีบัก 34px อยู่ล่างสุดของทุกสถานะ อ่านค่าแปดค่า: NET (มีเน็ตหรือไม่) · SRV (เวลาตอบของส่วนกลาง) · TUN (ไอพีในทันเนล) · UTC · UP (เวลาที่เครื่องเปิดมา) · GW · FW (เวอร์ชันเฟิร์มแวร์) · STATE ช่างที่เดินถึงตู้ต้องวินิจฉัยได้จากแถบนี้โดยไม่ต้องต่อเครื่องมืออื่น

แผงทดสอบอยู่นอกกรอบจอ เสมอ เพื่อไม่ให้ปุ่มทดสอบปนกับสิ่งที่คนขับเห็นจริง และปิดไว้เป็นค่าเริ่มต้น เปิดได้จากตัวเลือก showDevPanel เมื่อปิดแผง หัวจ่ายที่แสดงมาจากตัวเลือก deviceCode ซึ่งค่าเริ่มต้นคือ DP-0005

อยากเห็นสถานะ ทำอย่างไร
#0 · #1เลือก DP-0005 (ว่างและเปิดจ่าย) แล้วกดรีบูตที่แผงทดสอบ
#2เลือก DP-0003 — มีคำขอ REQ-4846 จองอยู่ (ไม่มีกำหนดเวลา) กด “ตั้งเวลา 2 นาที” เพื่อดูการนับถอยหลังและการหมดเวลา
#3เลือก DP-0004 — REQ-4845 ผูกไว้แล้ว · กด “ตั้งเวลา 5 นาที” เพื่อดูการยกเลิกเมื่อไม่เริ่มเติม
#4 · #5ที่ DP-0001 (REQ-4844 กำลังเติม) กดเริ่มมาตรวัด · ปรับอัตราไหล · กดถึงเพดานหรือหยุดจ่ายเพื่อดูใบสรุป
#6ขณะอยู่ที่ #2/#3/#4 กด “ยกเลิกจากส่วนกลาง” ในแผงจำลองแอปคนขับ
#7ขณะอยู่ที่ #4 ปิดสวิตช์ server — ต้องเห็นป้ายเหลืองและจ่ายต่อได้ ไม่ตกไป #9
#8เลือก DP-0006 (ปิดการจ่ายไว้) · หรือกดสวิตช์ปิดจ่ายระหว่าง #4 เพื่อยืนยันว่าไม่บังหน้าจอที่กำลังจ่าย
#9ที่หัวจ่ายว่าง ปิดสวิตช์ server — QR ต้องหายไป
#10เลือก DP-0002 (REQ-4847 ค้างที่ 18.75 ล.) แล้วกด “จำลองไฟดับ”
ตารางที่ 3 — วิธีเข้าถึงทุกสถานะสำหรับทีม QA ปุ่มที่แผงทดสอบเปลี่ยนเงื่อนไขจริง ไม่ใช่การกระโดดข้ามหน้าจอ ผลที่เห็นจึงเป็นผลของกฎเดียวกับระบบจริง

7 · ข้อกำหนดที่ห้ามละเมิด

อ่านอย่างเดียว — ไม่มีปุ่มยกเลิกที่ตู้ การปล่อยงานเกิดจากแอปคนขับ หลังบ้าน หรือการหมดเวลาเท่านั้น
ไม่มีตัวเลขความจุถัง — ทั้งจอและทุกสถานะ เพดานถูกบังคับใช้อย่างเงียบ
ไม่มีการเลื่อนจอ — ทุกสถานะพอดี 1024 × 600 แม้หัวจ่ายมีหัวย่อย 4 หัว แถบข้อมูลด้านขวาเลื่อนได้เฉพาะกรณีหัวจ่ายมีข้อมูลมากผิดปกติ
ไม่มีภาพเคลื่อนไหว — ยกเว้นตัวเลขมาตรวัดที่เดินจริงและแถบความคืบหน้า สถานะเปลี่ยนทันที เพื่อไม่ให้ใครสงสัยว่าค่าที่เห็นเป็นค่าปัจจุบันหรือไม่
รหัส 6 หลักตรวจที่ส่วนกลาง — ไม่ตรวจที่หัวจ่าย และไม่มีช่วงผ่อนผันข้ามหน้าต่างเวลา นาฬิกาเครื่องคลาดเกิน 5 วินาทีต้องขึ้นคำเตือน
ภาษา — ไทยทุกอย่างที่คนขับอ่าน · อังกฤษ mono สำหรับแถบดีบัก คีย์สถานะ และแผงทดสอบ · เรียกรถว่า “รถน้ำมันเคลื่อนที่”
ตารางที่ 4 — ข้อกำหนดหกข้อที่มาจากสภาพหน้างาน ไม่ใช่รสนิยมการออกแบบ ทุกข้อมีเคสทดสอบกำกับใน Tool - Test Case (KIOSK-01…KIOSK-19)